package moon.core.inheritance;

import java.util.ArrayList;
import java.util.List;

import moon.core.ObjectMoon;
import moon.core.classdef.ClassDef;
import moon.core.classdef.Type;
import moon.traverse.Visitor;

/**
 * Inheritance clause.
 * 
 * @author <a href="mailto:rmartico@ubu.es">Ra&uacute;l Marticorena</a>
 *
 */
@SuppressWarnings("serial")
public abstract class InheritanceClause extends ObjectMoon {
	
	/**
	 * ClassType of the ancestor.
	 */
	private Type ancestor;

	/**
	 * Class def that contains the inheritance clause.
	 */
	private ClassDef classDef;

	/**
	 * List of modifiers.
	 * 
	 * @see moon.core.inheritance.Modifier
	 */
	private List<Modifier> modifiers;

	/**
	 * Constructor.
	 * 
	 * @param ancestor ancestor
	 * @param classDef class that contains the inheritance clause
	 */
	public InheritanceClause(Type ancestor, ClassDef classDef) {
		this.set(ancestor);
		this.classDef = classDef;
		this.modifiers = new ArrayList<Modifier>();
	}

	/**
	 * Adds the modifier.
	 * 
	 * @param modifier modifier
	 */
	public void addModifier(Modifier modifier) {
		modifiers.add(modifier);
	}
	
	/**
	 * Removes the modifier.
	 * 
	 * @param modifier modifier
	 */
	public void removeModifier(Modifier modifier) {
		modifiers.remove(modifier);
	}

	/**
	 * Gets the type of the ancestor.
	 * 
	 * @return ancestor type
	 */
	public Type getType() {
		return ancestor;
	}

	/**
	 * Sets the direct ancestor.
	 * 
	 * @param ancestor ancestor
	 */
	public void set(Type ancestor) {
		this.ancestor = ancestor;
	}

	/**
	 * Accepts the visit.
	 * 
	 * Method from Pattern Design Visitor. By RMS.
	 * 
	 * @param visitor visitor
	 */
	public void accept(Visitor visitor) {
		// Hook method
		visitor.visit(this);
	}

	/**
	 * Gets the class in the inheritance clause.
	 * 
	 * @return direct ancestor
	 * @see #setClassDef
	 */
	public ClassDef getClassDef() {
		return classDef;
	}

	/**
	 * Sets the direct ancestor class.
	 * 
	 * @param classDef direct ancestor class
	 * @see #getClassDef
	 */
	public void setClassDef(ClassDef classDef) {
		this.classDef = classDef;
	}
	
	/**
	 * Gets modifiers.
	 * 
	 * @return modifiers
	 */
	public List<Modifier> getModifiers(){
		return this.modifiers;
	}
} // InheritanceClause
